import { LoadingOutlined, ReloadOutlined } from '@ant-design/icons'
import client, { UserUserVo } from '@lib/client'
import { Card, CardTable, Toolbar } from '@lib/components'
import { formatDate } from '@lib/utils/date'
import { useClientRequest } from '@lib/utils/useClientRequest'
import { Input, message, Popconfirm, Space, Tag, Tooltip } from 'antd'
import { IColumn } from 'office-ui-fabric-react/lib/DetailsList'
import { ScrollablePane } from 'office-ui-fabric-react/lib/ScrollablePane'
import React, { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'

import AssignRoleButton from './AssignRoleButton'
import BatchCreateUserButton from './BatchCreateUserButton'
import CreateUserButton from './CreateUserButton'
import SavePermissionButton from './SavePermissionButton'

const { Search } = Input

interface IExpandedUserItem extends UserUserVo {
  key: string
}

function expandUserItems(rows: UserUserVo[]): IExpandedUserItem[] {
  const expanded: IExpandedUserItem[] = []
  rows.forEach((row) => {
    expanded.push({
      key: row.id ? row.id + '' : '',
      ...row,
    })
  })
  return expanded
}

const addToFilter = (
  oldFilter: ((user: IExpandedUserItem) => boolean) | null,
  addedFilter: (user: IExpandedUserItem) => boolean
) =>
  !oldFilter
    ? addedFilter
    : (user: IExpandedUserItem) => oldFilter(user) && addedFilter(user)

export default function UserList() {
  const { t } = useTranslation()
  const [filterName, setFilterName] = useState('')
  const [userData, setUserData] = useState([] as IExpandedUserItem[])

  const { data: currentLogin } = useClientRequest((reqConfig) =>
    client.getInstance().infoWhoami(reqConfig)
  )

  const {
    data: listUserResponse,
    isLoading,
    error,
    sendRequest: listUser,
  } = useClientRequest((reqConfig) => client.getInstance().listUser(reqConfig))

  const handleDeleteUser = async (userId) => {
    const r = await client.getInstance().deleteUser({ user_id: userId })
    if (r.status == 200) {
      message.success('Success')
      listUser()
    }
  }

  const getFilterFn = () => {
    let filterFn

    if (filterName && filterName.trim().length > 0) {
      const normalizedFilter = filterName.toLowerCase()
      filterFn = addToFilter(
        filterFn,
        (user) =>
          user.name?.toLowerCase().includes(normalizedFilter) ||
          user.user_id?.includes(normalizedFilter) ||
          false
      )
    }

    return filterFn
  }

  const filterData = () => {
    const filterFn = getFilterFn()
    const list = expandUserItems(listUserResponse?.users ?? [])
    const filteredData = filterFn ? list.filter(filterFn) : list
    setUserData(filteredData)
  }

  useEffect(() => {
    filterData()
  }, [filterName, listUserResponse, currentLogin])

  const columns: IColumn[] = useMemo(
    () => [
      {
        name: t('user_list.list.user_table.columns.user_id'),
        key: 'user_id',
        minWidth: 100,
        maxWidth: 150,
        onRender: (row: IExpandedUserItem) => {
          return row.user_id
        },
      },
      {
        name: t('user_list.list.user_table.columns.name'),
        key: 'name',
        minWidth: 100,
        maxWidth: 150,
        onRender: (row: IExpandedUserItem) => {
          return row.name
        },
      },
      {
        name: t('user_list.list.user_table.columns.role'),
        key: 'role',
        minWidth: 150,
        maxWidth: 300,
        onRender: (row: IExpandedUserItem) => {
          return row.role?.map((item) => (
            <Tag color="geekblue" key={item}>
              {item}
            </Tag>
          ))
        },
      },
      {
        name: t('user_list.list.user_table.columns.login_time'),
        key: 'login_time',
        minWidth: 100,
        maxWidth: 150,
        onRender: (row: IExpandedUserItem) => {
          if (row.login_time) {
            return formatDate(new Date(row.login_time))
          }

          return row.login_time
        },
      },
      {
        name: t('user_list.list.user_table.columns.action'),
        key: 'action',
        minWidth: 100,
        maxWidth: 300,
        onRender: (row: IExpandedUserItem) => {
          return (
            <Space>
              <Popconfirm
                placement="bottom"
                title={t('user_list.button.delete_user.tip')}
                onConfirm={() => handleDeleteUser(row.user_id)}
                okText={t('user_list.button.delete_user.submit')}
                cancelText={t('user_list.button.delete_user.cancel')}
              >
                <a href="">{t('user_list.button.delete_user.title')}</a>
              </Popconfirm>
              <AssignRoleButton refresh={listUser} userId={row.user_id} />
              <SavePermissionButton refresh={listUser} userId={row.user_id} />
            </Space>
          )
        },
      },
    ],
    [t]
  )

  return (
    <div
      style={{
        height: 'calc(100vh - 48px)',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      <Card>
        <Toolbar>
          <Space>
            <Search
              onChange={(e) => {
                setFilterName(e.target.value)
              }}
            />
            {/* <CreateUserButton refresh={listUser} /> */}
            <BatchCreateUserButton refresh={listUser} />
          </Space>
          <Space>
            <Tooltip title={t('statement.pages.overview.toolbar.refresh')}>
              {isLoading ? (
                <LoadingOutlined />
              ) : (
                <ReloadOutlined onClick={listUser} />
              )}
            </Tooltip>
          </Space>
        </Toolbar>
      </Card>

      <div style={{ height: '100%', position: 'relative' }}>
        <ScrollablePane>
          <CardTable
            cardNoMarginTop
            loading={isLoading}
            columns={columns}
            items={userData}
            errors={[error]}
          />
        </ScrollablePane>
      </div>
    </div>
  )
}
